const { ChatGroupMessageModel } = require('../models/chat_group_message')
const { ChatGroupUserRelationModel } = require('../models/chat_group_user_relation')
const { ChatPrivateMessageModel } = require('../models/chat_private_message')
const { ChatUserRelationModel } = require('../models/chat_user_relation')
const { ChatNewFriendsModel } = require('../models/chat_new_friends')
const { SocketModel } = require('../models/socket')
const logger = require('../utils/logger')

module.exports = function (httpServer) {
  // 得到 IO 对象
  const { Server } = require('socket.io')
  const io = new Server(httpServer, {
    cors: {
      origin: ['http://localhost:9527', 'http://localhost:8086'],
      allowedHeaders: ['my-custom-header'],
      credentials: true
    }
  })

  io.on('connection', function (socket) {
    let socketId = socket.id
    // 登录
    socket.on('login', async (data) => {
      try {
        console.log("socket-login");
        const { user_id } = data
        logger.info('socket.io', 'login', 'request', data)
        // 更新用户socketId
        await SocketModel.addUserSocketId(user_id, socketId)

        // 查找在线好友列表并通过socket_id通知好友
        const friends = await SocketModel.findFriendsId(user_id)
        logger.info('socket.io', 'login', 'friends', friends, socketId)
        friends.map((friend) => {
          let sendData = Object.assign({}, data, { user_alias: friend.user_alias })
          io.to(friend.socket_id).emit('friendOnline', sendData)
        })

        // 获取所有未读消息
        const unread = await SocketModel.getAllUnread(user_id);
        logger.info('socket.io', 'login', 'unread', unread)
        io.to(socketId).emit("sendUnread", unread)

        // 获取消息列表
        const friendMessageList = await ChatPrivateMessageModel.findByUserId(user_id)
        const groupMessageList = await ChatGroupMessageModel.findByUserId(user_id)
        logger.info('socket.io', 'messageList', 'messageList', { friendMessageList, groupMessageList })
        io.to(socketId).emit("messageList", { friendMessageList, groupMessageList })

        // 获取群组列表
        const groupList = await ChatGroupUserRelationModel.findByUserId(user_id)
        logger.info('socket.io', 'groupList', 'groupList', unread)
        io.to(socketId).emit("groupList", groupList)

        // 获取好友列表
        const friendList = await ChatUserRelationModel.findAll(user_id)
        logger.info('socket.io', 'login', 'friendList', friendList)
        io.to(socketId).emit("friendList", friendList)

        // 获取新的朋友列表数据
        const newFriendList = await ChatNewFriendsModel.find(user_id)
        logger.info('socket.io', 'login', 'newFriendList', newFriendList)
        io.to(socketId).emit("newFriendList", newFriendList)
      } catch (error) {
        logger.info('socket.io', 'login', 'error', error.message)
      }
    })

    // 更新
    socket.on('update', async (data) => {
      const { user_id } = data
      if (!user_id) {
        return
      }
      logger.info('socket.io', 'update', 'request', data)
      await SocketModel.addUserSocketId(user_id, socketId)

      // 获取所有未读消息
      const unread = await SocketModel.getAllUnread(user_id);
      logger.info('socket.io', 'login', 'unread', unread)
      io.to(socketId).emit("sendUnread", unread)

      // 获取消息列表
      const friendMessageList = await ChatPrivateMessageModel.findByUserId(user_id)
      const groupMessageList = await ChatGroupMessageModel.findByUserId(user_id)
      logger.info('socket.io', 'messageList', 'messageList', { friendMessageList, groupMessageList })
      io.to(socketId).emit("messageList", { friendMessageList, groupMessageList })

      // 获取群组列表
      const groupList = await ChatGroupUserRelationModel.findByUserId(user_id)
      logger.info('socket.io', 'groupList', 'groupList', unread)
      io.to(socketId).emit("groupList", groupList)

      // 获取好友列表
      const friendList = await ChatUserRelationModel.findAll(user_id)
      logger.info('socket.io', 'login', 'friendList', friendList)
      io.to(socketId).emit("friendList", friendList)

      // 获取新的朋友列表数据
      const newFriendList = await ChatNewFriendsModel.find(user_id)
      logger.info('socket.io', 'login', 'newFriendList', newFriendList)
      io.to(socketId).emit("newFriendList", newFriendList)
    })

    // 添加好友请求
    socket.on('sendRequest', async (data) => {
      logger.info('socket.io', 'sendRequest', 'request', data)
      try {
        // 获取 to_user 的 socketid
        const toInfo = await SocketModel.getUserSocketId(data.to)
        logger.info('socket.io', 'sendRequest', 'toInfo', toInfo)
        if (toInfo.socket_id) {
          // 前端更新 获取通知数量
          const noticeNum = await SocketModel.getAllUnread(data.to)
          logger.info('socket.io', 'sendRequest', 'noticeNum', noticeNum)
          const sendData = Object.assign({}, data, noticeNum[0])
          io.to(toInfo.socket_id).emit('getResponse', sendData)
        }
      } catch (error) {
        logger.error('socket.io', 'sendRequest', 'error', error)
      }
    })

    // 私聊
    socket.on('sendPrivateMsg', async (data) => {
      logger.info('socket.io', 'sendPrivateMsg', 'request', data)
      const { from, to, content } = data
      // 判断是否是好友
      try {
        const isFriends = await ChatUserRelationModel.check(from, to)
        logger.info('socket.io', 'sendPrivateMsg', 'isFriends', isFriends)
        if (!isFriends.length) {
          const fromInfo = await SocketModel.getUserSocketId(from)
          if (fromInfo.socketid) {
            io.to(socketid).emit('erroMsg', '暂不是好友信息')
          }
        } else {
          // 获取 to_user 的 socketid
          const toInfo = await SocketModel.getUserSocketId(data.to)
          logger.info('socket.io', 'sendPrivateMsg', 'toInfo', toInfo)
          if (toInfo.socket_id) {
            // 通知接受者 接受消息
            console.log(toInfo.socket_id, "toInfo.socket_id");
            io.to(toInfo.socket_id).emit('getPrivateMsg', data)
            //接受者接收到消息,  /v1/chats/message
          }
        }
      } catch (error) {
        logger.error('socket.io', 'sendPrivateMsg', 'error', error)
      }
    })

    // 群聊
    socket.on('sendGroupMsg', async (data) => {
      const { from, content, group_id } = data
      logger.info('socket.io', 'sendGroupMsg', 'request', data)
      try {
        // 获取群内成员
        const groupMember = await ChatGroupUserRelationModel.findMemberId(
          group_id
        )
        logger.info('socket.io', 'sendGroupMsg', 'groupMember', groupMember)
        // 保存群消息
        const saveRes = await ChatGroupMessageModel.saveMsg(
          group_id,
          from,
          content,
          groupMember
        )
        logger.info('socket.io', 'sendGroupMsg', 'saveRes', saveRes)
        // 获取群好友 socket_id
        const members = groupMember.filter((m) => m.user_id !== from)
        const groupMemberSocketIds = await SocketModel.findMembersId(members)
        groupMemberSocketIds.map((member) => {
          io.to(member.socket_id).emit('getGroupMsg', data)
        })
        // io.sockets.emit("getGroupMsg", data);
      } catch (error) {
        io.to(socket_id).emit('erroMsg', error.message)
      }
    })

    // 离线
    socket.on('disconnect', async () => {
      try {
        const userInfo = await SocketModel.getUserIdBySocketId(socketId);
        if (userInfo.user_id) {
          await SocketModel.removeUserSocketId(userInfo.user_id)
          // 查找在线好友列表并通过socket_id通知好友
          const friends = await SocketModel.findFriendsId(user_id)
          logger.info('socket.io', 'login', 'friends', friends)
          friends.map((friend) => {
            let sendData = Object.assign({}, data, { user_alias: friend.user_alias })
            io.to(friend.socket_id).emit('userOffline', sendData)
          })
        }
      } catch (error) {
        logger.error(error.message)
      }
    })

    // 读取信息
    socket.on('readMsg', async (data) => {
      logger.info('socket.io', 'readMsg', 'request', data)
      try {
        const { from, to } = data;
        if (from && to) {
          await ChatPrivateMessageModel.clearUnread(from, to)
          // 获取所有未读消息
          const unread = await SocketModel.getAllUnread(to);
          logger.info('socket.io', 'login', 'unread', unread)
          io.to(socketId).emit("sendUnread", unread)
        }
      } catch (error) {
        logger.error(error.message)
      }
    })


    // 退出
    socket.on('logout', async (data) => {
      try {
        const { user_id } = data
        if (user_id) {
          await SocketModel.removeUserSocketId(user_id)
          // 查找在线好友列表并通过socket_id通知好友
          const friends = await SocketModel.findFriendsId(user_id)
          logger.info('socket.io', 'logout', 'friends', friends)
          friends.map((friend) => {
            let sendData = Object.assign({}, data, { user_alias: friend.user_alias })
            io.to(friend.socket_id).emit('userOffline', sendData)
          })
        }
      } catch (error) {
        logger.error(error.message)
      }
    })
  })
}
